from queue import PriorityQueue
import time
import threading

from device import DeviceBase
from .task_base import TaskBase

class Interface:
    def __init__(self, app_name:str, device:DeviceBase):
        self.app_name = app_name#当前应用的名字
        self.interface_name = None#当前界面的名字
        self.device = device
        self.waiting_tasks = PriorityQueue()
        self.blocked_tasks = []
        self.task_map = {}  # 用于快速查找任务
        self.activated = True
        self.order = 0
        self.lock = threading.Lock()
    
    def run(self):
        threading.Thread(target=self.monitor_priorities, daemon=True).start()
        while self.activated:
            try:
                _, _, task_name = self.waiting_tasks.get_nowait()
                if task_name not in self.task_map.keys():
                    continue
                self.refresh_interface_info()
                if self.interface_name != self.task_map[task_name].get_interface_name():
                    self.change_interface(self.task_map[task_name].get_interface_name())
                self.task_map[task_name].run()
                if self.task_map[task_name].is_complete():
                    continue
                self.queue_task(task_name)
            except Exception as e:
                time.sleep(1)

    def change_interface(self, name:str):
        '''
        跳转到指定的界面
        '''
        raise NotImplementedError()
    
    def refresh_interface_info(self, interface_name:str=None):
        '''
        刷新当前的界面信息
        '''
        raise NotImplementedError()
    
    def add_task(self, task:TaskBase):
        '''
        添加任务调度
        '''
        if task.task_name not in self.task_map.keys():
            self.task_map[task.task_name] = task
            self.queue_task(task.task_name)
        else:
            raise f"{task.task_name} is already in the task queue"
    
    def queue_task(self, task_name:str):
        '''
        添加任务到合适队列
        '''
        if task_name in self.task_map.keys():
            if self.waiting_tasks.qsize() == 0:
                self.order = 0
            if self.task_map[task_name].is_activated():
                self.lock.acquire()
                self.waiting_tasks.put((-self.task_map[task_name].current_priority, self.order, task_name))
                self.lock.release()
                self.order += 1
            else:
                self.lock.acquire()
                self.blocked_tasks.append(task_name)
                self.lock.release()

    def delete_task(self, task:TaskBase):
        '''
        删除任务
        '''
        if task.task_name in self.task_map.keys():
            del self.task_map[task.task_name]

    def monitor_priorities(self):
        while self.activated:
            length = len(self.blocked_tasks)
            while length:
                task_name = self.blocked_tasks.pop(0)
                self.task_map[task_name].update_state()
                self.queue_task(task_name)
                length -= 1
            time.sleep(1)
